home *** CD-ROM | disk | FTP | other *** search
/ Directorty Opus 5 - Magellan 2 / Opus 5 - Magellan 2.iso / Extras / D51_NUSource / Source / Routines / Data.s < prev    next >
Text File  |  1996-01-06  |  43KB  |  1,117 lines

  1. *=- INFO -=****************************************************************************
  2. * Data Subroutines. (Number/String Handling, etc etc)                                 *
  3. * Unless otherwise stated, all routines are by Leo 'Nudel' Davidson                   *
  4. *=- Notes -===========================================================================*
  5. * o Make sure all routines using the CharCopy commands check d7 as WORD, not longword *
  6. * o Routines using upper-case do *NOT* currently use the local.library.               *
  7. *   (Only chars A-Z are handled, which is good enough for the jobs it's used for).    *
  8. *=- To Do -===========================================================================*
  9. * o Use IFGT or similar to define how much of the ascii->number routine is included.  *
  10. * o The random number routines need sorting out (I think the "new" one could be made  *
  11. *   good with one or two minor adjustments -- as it is it isn't perfect).             *
  12. *=- History (worth mentioning) -======================================================*
  13. * o Version 2.00                                                                      *
  14. *   Ancient history deleted.                                                          *
  15. ***************************************************************************************
  16.  
  17.  
  18. ***************************************************************************************
  19. *: Data Handling Subroutines :::::::::::::::::::::::::::::::::::::::::::::::::::::::::*
  20. ***************************************************************************************
  21. ;DATA_CMP_NUL    ; Compare Two Null-Term strings.
  22. ;DATA_SR_FACS    ; Serach, Forwards, Case Sensitive - String, Till ADR
  23. ;DATA_SR_BACS    ; Serach, Backwards, Case Sensitiv - String, Till ADR
  24. ;DATA_SR_EITH    ; Search, Forwards, Case Sensitive - 1 of 2 Bytes.
  25. ;DATA_SR_AdrB    ; Search, Forwards, Case Sensitive - Byte, Till ADR
  26. ;DATA_SRBAdrB    ; Serach, Backwards, Case Sensitiv - Byte, Till ADR
  27. ;DATA_UPPACAZ    ; Upper-Case.
  28. ;DATA_UPPA_NT    ; Upper-Case NullTerm data.
  29. ;DATA_JOINNT    ; Join two null-terminated strings.
  30. ;DATA_JOINARRAY    ; Join together an array of strings.
  31. ;DATA_CHARCOP    ; Copy x chars with specified terminator.
  32. ;DATA_CHARCOPNL    ; Copy x chars with Null-Term and specified terminator.
  33. ;DATA_CHARCNT    ; Copy x chars with Null-Term
  34. ;DATA_COPYCN2    ; Copy x chars with Null-Term, don't copy Null.
  35. ;DATA_COPYCN3    ; Copy chars with Null-Term, don't copy Null, no Length
  36. ;DATA_CPYDUAL    ; Copy x chars with two specified terminators
  37. ;DATA_WRCHARS    ; Write specied char x times.
  38. ;DATA_SPAOVER    ; Overlay output with (space) padding.
  39. ;DATA_N2AAuto    ; Automatically selects the needed NUM2ASC routine.
  40. ;DATA_NUM2ASC    ; Raw Number to ASCII conversion.
  41. ;DATA_N2ASCFT    ; Raw Number to ASCII conversion, to Format-Text Blocks.
  42. ;DATA_AS2NUNT    ; ASCII to Raw Number conversion, expansion for NT data.
  43. ;DATA_ASC2NUM    ; ASCII to Raw Number conversion.
  44. ;DATA_TIMECON    ; Time Convertion routine (ASCII HH:MM -> Raw Minutes).
  45. ;DATA_PADZERO    ; Space-Pad Zeros from start of ASCII number.
  46. ;DATA_DQUOTER    ; De-Quoter (Nulls 1st found Quote) for #-1 Term String.
  47. ;DATA_EXPLODE    ; Imploder Decrunch.
  48. ;DATA_NULLLEN    ; Calculate the length of a Null-Term String.
  49. ;DATA_RNDBYTE    ; Generate a BYTE sized random number.
  50. ;DATA_RNDWORD    ; Generate a WORD sized random number.
  51. ;DATA_RNDLEPP    ; Generate a WORD sized random number (by Andrew Leppard)
  52. ;DATA_NUWRAND    ; "New" Random Number (Word) Routines.
  53. ;DATA_RAWDOFMT    ; RawDoFmt() routine.
  54. ;    INCLUDE    ASM:Source/Routines/Data.s
  55. ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=;
  56.     IFD    DATA_CMP_NUL
  57. *= COMPARE NULL TERMINATED =*************************************************
  58. * (a0) = Start of 1st String to cmp   * (a1) = Start of 2nd String to cmp   *
  59. *===========================================================================*
  60. * After BSRing this routine: BEQ to routine for if they are the same, or,   *
  61. * -------------------------- BNE to routine for if they are not the same.   *
  62. *****************************************************************************
  63. NCmp    Cmpm.b    (a0)+,(a1)+        Compare the two bytes.
  64.     Bne.s    NCmp_NE            If not equal, Branch.
  65. ;;;;;;; *THE BRANCH TO NCmp_NE **MUST** BE DONE AS A BNE!!*
  66.     Tst.b    -1(a0)            Did we just check two nulls?
  67.     Bne.s    NCmp            If not, Check the next bytes...
  68. NCmp_NE    RTS
  69.     ENDC
  70.  
  71.     IFD    DATA_SR_FACS
  72. *= SEARCH FORWARDS, CASE SENSITIVE, TILL ADR =*******************************
  73. * a0 - Start of area to be searched   * a1 = <Preserve a0>       (-Varies-) *
  74. * a2 - String to search for, NULL end * a3 = <Preserve a2>       (-Varies-) *
  75. * d3 = (Gap Area » Searched)          * d4 = <Temp>              (-Varies-) *
  76. * d6 - Adr to stop searching at.      *                                     *
  77. *===========================================================================*
  78. * If d6 reached before a2 found then d3 returns #-1                         *
  79. *****************************************************************************
  80. SAdrStr    Move.l    a0,a1            Preserve a0 pointer
  81.     Move.l    a2,a3            Preserve a2 pointer
  82.     Moveq.l    #0,d4            Clear for length of searched.
  83. SSALoop    Tst.b    (a3)            Are we at the end of the compare?
  84.     Beq.s    SSAFond            Yes=End part.
  85.     Cmp.l    d6,a1            If past end of search area,
  86.     Bge.s    SSANotF            end search.
  87.     Cmpm.b    (a1)+,(a3)+        Check The letter.
  88.     Beq.s    SSAFdCh            Match=Increment both counters.
  89.     Move.l    a2,a3            Reset a3 to start of searched.
  90.     Sub.l    d4,a1            Rechechk Chars *IMPORTANT*
  91. ;                    Without, partial matches followed
  92. ;                    by the real thing would not find it!
  93.     Moveq.l    #0,d4            Reset "Length" of searched to 0.
  94.     Bra.s    SSALoop            Loop it.
  95. SSAFdCh    Addq.l    #1,d4            Add one to length of searched
  96.     Bra.s    SSALoop            Loop it.
  97. SSANotF    Moveq.l    #-1,d3            String not found: Negative # in d3
  98.     RTS
  99. SSAFond    Move.l    a1,d3            To be returned in d3...
  100.     Sub.l    a0,d3            -._ Get length from Start of search to
  101.     Sub.l    d4,d3            -'  start of Searched.
  102.     RTS
  103.     ENDC
  104.  
  105.     IFD    DATA_SR_EITH
  106. *= SEARCH - FORWARDS - CASE SENSITIVE - FOR EITHER SPECIFIED BYTES =*********
  107. * d0 - First Byte to end search on   * a0 - Start of Search area            *
  108. * d1 - Second Byte to end search on  * a1 = <Preserves a0>                  *
  109. * d3 = (Length a0 -> (d0) or (d1))   *                                      *
  110. *===========================================================================*
  111. * After BSRing this routine: BEQ to routine for if the First (d0) is Found  *
  112. * -------------------------- BNE to routine for if the Secnd (d1) is Found  *
  113. *****************************************************************************
  114. SR_Eith    Moveq    #0,d3            Clear d3 ready for count.
  115.     Move.l    a0,a1            Preserve a0
  116. SR_ELop    Cmp.b    (a1),d0            -.
  117.     Beq.s    SR_ED0E             |_ If either byte found,
  118.     Cmp.b    (a1)+,d1         |  the job is done.
  119.     Beq.s    SR_ED1E            -'
  120.     Addq.l    #1,d3            Increment Distance counter
  121.     Bra.s    SR_ELop            Check the next Byte.
  122. SR_ED0E    Move    #EqCCR,CCR        d0 Was found. (Set Z CCR "Equal")
  123.     RTS                Return
  124. SR_ED1E    Move    #NeCCR,CCR        d1 Was found. (Clear Z CCR "NotEq")
  125.     RTS                Return
  126.     ENDC
  127.  
  128.     IFD    DATA_SR_BACS
  129. *= SEARCH - BACKWARDS - CASE SENSITIVE - TILL ADR =**************************
  130. * a0 - End+1 of area to be searched   * a1 = <Preserve a0>       (-Varies-) *
  131. * a2 - Backwards String to search for * a3 = <Preserve a2>       (-Varies-) *
  132. *    \_ Null-Terminate it.            * d4 = <Temp>              (-Varies-) *
  133. * d6 - Adr to Stop Searching at.      * d7 = <Temp>                         *
  134. * d3 = (Length from End of            *                                     *
  135. *    \_ area to Start Search String)  *                                     *
  136. *===========================================================================*
  137. * If d6 reached before a2 found then d3 returns #-1                         *
  138. *****************************************************************************
  139. SBaStAd    Move.l    a0,a1            Preserve a0 pointer
  140.     Move.l    a2,a3            Preserve a2 pointer
  141.     Moveq.l    #0,d4            Clear for length of searched.
  142. SBSALop    Tst.b    (a3)            Found all of the Search string?
  143.     Beq.s    SBSAFnd            Yes=End part.
  144.     Move.b    -(a1),d7
  145.     Cmp.l    d6,a1            -._ If at "END" (Top) of search area,
  146.     Ble.s    SBSANot            -'  not found.
  147.     Cmp.b    (a3)+,d7        Check the letter with string.
  148.     Beq.s    SBSAFCh            Match=Increment both counters.
  149.     Move.l    a2,a3            Reset a3 to start of searched.
  150.     Add.l    d4,a1            Rechechk Chars *IMPORTANT*
  151. ;                    Without, partial matches followed
  152. ;                    by the real thing would not find it!
  153. ;                    Rem: When checking backwards, ADD!
  154.     Moveq    #0,d4            Reset "Length" of searched to 0.
  155.     Bra.s    SBSALop            Loop it.
  156. SBSAFCh    Addq.l    #1,d4            Add one to length of searched
  157.     Bra.s    SBSALop            Loop it.
  158. SBSANot    Moveq.l    #-1,d3            String not found: #-1 in d3
  159.     RTS
  160. SBSAFnd    Move.l    a0,d3            -._ Get Length from String to end of
  161.     Sub.l    a1,d3            -'  file. (Add d4 for end of string.)
  162.     RTS
  163.     ENDC
  164.  
  165.     IFD    DATA_SR_AdrB
  166. *= SEARCH, FORWARDS, CASE SENSITIVE FOR BYTE, TILL ADR =*********************
  167. * d0 - Byte to search for.           * d3 = (Length a0»byte, or #-1)        *
  168. * a0 - Area to search in.            * a1 = <Preserve a0>                   *
  169. * d6 - Adr to stop searching at.     *                                      *
  170. *****************************************************************************
  171. SAdrByt    Move.l    a0,a1            Preserve a0
  172.     Bra.s    SAdBJmp
  173. SAdBLop    Cmp.b    (a1)+,d0        Check for the char...
  174.     Beq.s    SAdBFnd
  175. SAdBJmp    Cmp.l    d6,a0            -._ If not past the end of area,
  176.     Blt.s    SAdBLop            -'  then continue the search.
  177. SAdBNot    Moveq    #-1,d3            Else, NOT FOUND.
  178.     RTS
  179. SAdBFnd    Move.l    a1,d3            To be returned in d3...
  180.     Sub.l    a0,d3            Get length from Start to Found.
  181.     RTS
  182.     ENDC
  183.  
  184.     IFD    DATA_SRBAdrB
  185. *= SEARCH, BACKWARDS, CASE SENSITIVE FOR BYTE, TILL ADR =********************
  186. * d0 - Byte to search for.           * d3 = (Length a0»byte, or #-1)        *
  187. * a0 - End+1 Area to search in.      * a1 = <Preserve a0>                   *
  188. * d6 - Adr to stop searching at.     *                                      *
  189. *****************************************************************************
  190. SBAdByt    Move.l    a0,a1            Preserve a0
  191.     Bra.s    SBABJmp
  192. SBABLop    Cmp.b    -(a1),d0        Check for the char...
  193.     Beq.s    SBABFnd
  194. SBABJmp    Cmp.l    d6,a0            -._ If not past the end of area,
  195.     Bge.s    SBABLop            -'  then continue the search.
  196. SBABNot    Moveq    #-1,d3            Else, NOT FOUND.
  197.     RTS
  198. SBABFnd    Move.l    a0,d3            To be returned in d3...
  199.     Sub.l    a1,d3            Get length from Start to Found.
  200.     RTS
  201.     ENDC
  202.  
  203.     IFD    DATA_UPPACAZ
  204. *= UPPER =*******************************************************************
  205. * a2 = Adr Start Text (End+1)        * d0 = Len Text to uppdercase          *
  206. * d1 = <Temp>                 (#"a") * d2 = <Temp>                   (#"z") *
  207. *****************************************************************************
  208. Upper    Move.b    #"a",d1            -._ For faster
  209.     Move.b    #"z",d2            -'  Upper Case
  210.     Bra.s    UpperJM
  211. UpperMA    Cmp.b    (a2)+,d1        -.
  212.     Bgt.s    UpperJM             |_ If not a lowercase ASCII letter,
  213.     Cmp.b    -1(a2),d2         |  leave it alone.
  214.     Blt.s    UpperJM            -'
  215.     Sub.b    #32,-1(a2)        Convert to UpperCase
  216. UpperJM    Dbra    d0,UpperMA        Do x number of letters
  217.     RTS
  218.     ENDC
  219.  
  220.     IFD    DATA_UPPA_NT
  221. *= UPPER - NULL TERMINATED  =************************************************
  222. * a2 = Adr Start Text (End+1)        *                                      *
  223. * d1 = <Temp>                 (#"a") * d2 = <Temp>                   (#"z") *
  224. *****************************************************************************
  225. UperNul    Move.b    #"a",d1            -._ For faster
  226.     Move.b    #"z",d2            -'  Upper Case
  227. UperNLo    Tst.b    (a2)+            Null Terminator? (End of Text)
  228.     Beq.s    UperNuD            Yes=Done...
  229.     Cmp.b    -1(a2),d1        -.
  230.     Bgt.s    UperNLo             |_ If not a lowercase ASCII letter,
  231.     Cmp.b    -1(a2),d2         |  leave it alone.
  232.     Blt.s    UperNLo            -'
  233.     Sub.b    #32,-1(a2)        Convert to UpperCase
  234.     Bra.s    UperNLo            Do all letters
  235. UperNuD    RTS
  236.     ENDC
  237.  
  238.     IFD    DATA_CHARCOP
  239. *= COPY CHARS TERMINATED =***************************************************
  240. * a0 = Start (End) Source String     * a1 = Start (End+1) Destin Area       *
  241. * d7 = Max Length for Dest   (below) * d0 - Chr to End Copy on (not copied) *
  242. *===========================================================================*
  243. * Branch to CopyChr                                                         *
  244. * Special version for Null-Term data below.                                 *
  245. * d7.w returns (#-1) if the destination is filled. If it is not filled,     *
  246. * d7.w returns the remaining length of the buffer. ***d7 RETURNS IN A WORD***
  247. *****************************************************************************
  248. CopChrL    Cmp.b    (a0),d0            End Char?
  249.     Beq.s    CopyDon            Yes=Copy Done
  250.     Move.b    (a0)+,(a1)+        Else, Copy until end of destin.
  251. CopyChr    Dbra    d7,CopChrL
  252. CopyDon    Rts
  253.     ENDC
  254.  
  255.  
  256.     IFD    DATA_CHARCOPNL
  257. *= Copy Null-term, w/ Stop Character =*********************************= 12-Aug-1995 =*
  258. *  Inputs: a0 - Null-term Source String, which _may_ have d0.b char in it.          *
  259. *          a1 - Destination buffer                              *
  260. *          d7 - Length for Destinatin buffer                          *
  261. *        d0.b - Chr to End Copy on if found before the null (not copied)          *
  262. * Outputs: a1 - Remainder of destination buffer.                      *
  263. *        d7.w - Remaining length of destination buffer. *** RETURNS AS WORD-SIZE! *** *
  264. *=====================================================================================*
  265. *   Notes: Branch to "CopyChr_Null"                              *
  266. *        : The resultant string will always be null-terminated.                  *
  267. *        : "Buffer_Overflow" is called AUTOMATICALLY on error.                  *
  268. *        : d7 returns a word-size number.                          *
  269. ***************************************************************************************
  270. CopyChr_Null
  271.     DBra    d7,CopyChr_Null_Loop
  272.     Bra.s    Buffer_Overflow        Buffer overflow error if it filled.
  273. CopyChr_Null_Loop
  274.     Cmp.b    (a0),d0            End Char?
  275.     Beq.s    CopyDo0_AS        Yes=Copy Done
  276.     Move.b    (a0)+,(a1)+        Else, Copy until end of destin.
  277.     DBeq    d7,CopyChr_Null_Loop
  278.     Bne.s    Buffer_Overflow        Buffer overflow error if it filled.
  279.     RTS
  280. CopyDo0_AS
  281.     SF    (a1)            Null-terminate the string.
  282.     RTS
  283.     ENDC
  284.  
  285.  
  286.     IFD    DATA_JOINNT
  287. *= Join Null-Term =****************************************************= 18-Aug-1995 =*
  288. *  Inputs: (a0) - First half of string to join together, and buffer to write into.    *
  289. *       d7.w - Length of (a0) buffer.                          *
  290. *       (a1) - Second half of string to join together.                  *
  291. * Outputs: A joined, null-terminated string.                          *
  292. *       d7.w - Remaining length of (a0) buffer.                      *
  293. *   Notes: Call the Join_NT label.                              *
  294. *     : d7 returns a WORD sized number.                          *
  295. *     : Buffer_Overflow is handled automatically.                      *
  296. ***************************************************************************************
  297. JNT_Lp1    Tst.b    (a0)+            -.
  298. Join_NT    DBeq    d7,JNT_Lp1         |_ Find the end of the string and update
  299.     Bne.s    Buffer_Overflow         |  the remaining length of the buffer.
  300.     Subq.l    #1,a0            -'
  301.  
  302.     DBra    d7,JNT_Lp2
  303.     Bra.s    Buffer_Overflow
  304. JNT_Lp2    Move.b    (a1)+,(a0)+        Copy the next char
  305.     DBeq    d7,JNT_Lp2        Copy 'till end of dest or null reached
  306.     Bne.s    Buffer_Overflow
  307.     RTS
  308.     ENDC
  309.  
  310.  
  311.  
  312.  
  313.     IFD    DATA_JOINARRAY
  314. *= Join Array Null-Term =***********************************************= 9-Sep-1995 =*
  315. *  Inputs: (a0) - Temp.                                      *
  316. *       (a1) - Buffer to write result into.                          *
  317. *       d7.w - Length of (a1) buffer.                          *
  318. *       (a2) - Array of string pointers, ending with a NULL longword.          *
  319. *        d6  - Temp.                                      *
  320. *        d5  - Temp.                                      *
  321. *        d4  - Temp.                                      *
  322. * Outputs: Strings in the array are joined.                          *
  323. *   Notes: A space is inserted between each string in the array.              *
  324. *     : Any strings in the array with spaces in will be surrounded by quotes.      *
  325. *     : Buffer_Overflow is handled automatically.                      *
  326. ***************************************************************************************
  327. JoinArray
  328.     Tst.l    (a2)            End of array?
  329.     Beq.s    JoinArray_End2        If so, null-terminate the result.
  330.     Move.b    #" ",d6            Space for speed.
  331.     Move.b    #'"',d5            Quote for speed.
  332. JoinArray_MainLoop
  333.     Tst.l    (a2)            End of array?
  334.     Beq.s    JoinArray_End        If so, null-terminate the result.
  335.  
  336.     Move.l    (a2)+,a0        String from array to source
  337.  
  338.     Move.l    a0,-(SP)        Preserve source string.
  339.  
  340.     Sub.l    d4,d4            No quotes, unless required.
  341.  
  342. JoinArray_QuoteLoop
  343.     Tst.b    (a0)            End of string?
  344.     Beq.s    JoinArray_QuoteFixed    No quotes, leave it as-is.
  345.     Cmp.b    (a0)+,d6        Quote?
  346.     Bne.s    JoinArray_QuoteLoop    If not, check the rest.
  347.  
  348.     Addq.l    #1,d4            #1 -> d4 so quotes are added.
  349.  
  350. JoinArray_QuoteFixed
  351.     Move.l    (SP)+,a0        Restore source string.
  352.  
  353.     Tst.l    d4            -._ Don't wrote a quote
  354.     Beq.s    JoinArray_QuoteSkip1    -'  if it isn't required.
  355.     Subq.l    #1,d7            Update the remaining length of the buffer.
  356.     Ble    Buffer_Overflow        Buffer Overflow -> Abort program.
  357.     Move.b    d5,(a1)+        Write the quote.
  358. JoinArray_QuoteSkip1
  359.  
  360.     DBra    d7,JoinArray_CopyLoop
  361.     Bra    Buffer_Overflow        Buffer Overflow -> Abort program.
  362. JoinArray_CopyLoop
  363.     Move.b    (a0)+,(a1)+
  364.     DBeq    d7,JoinArray_CopyLoop
  365.     Bne    Buffer_Overflow        Buffer Overflow -> Abort program.
  366.  
  367.     Tst.l    d4            -._ Don't wrote a quote
  368.     Beq.s    JoinArray_QuoteSkip2    -'  if it isn't required.
  369.     Subq.l    #1,d7            Update the remaining length of the buffer.
  370.     Ble    Buffer_Overflow        Buffer Overflow -> Abort program.
  371.     Move.b    d5,-1(a1)        Write the quote (Over the null)
  372.     Move.b    d6,(a1)+        Space between each string.
  373. JoinArray_QuoteSkip2
  374.  
  375.     Move.b    d6,-1(a1)        Space between each string (over null).
  376.     Bra.s    JoinArray_MainLoop
  377.  
  378. JoinArray_End
  379.     SF    -(a1)            Null-terminate the resultant string.
  380. ;;;;;;;                    (Written over the last space).
  381.     RTS
  382. JoinArray_End2
  383.     SF    (a1)            Null-terminate the empty buffer.
  384.     RTS
  385.     ENDC
  386.  
  387.  
  388.     IFD    DATA_CHARCNT
  389. *= COPY CHARS NULL TERMINATED =**********************************************
  390. * a0 = Start (End) Source String     * a1 = Start (End+1) Destin Space      *
  391. * d7 = Max Length for Dest   (below) *                                      *
  392. *===========================================================================*
  393. * Branch to CopyCNT                                                         *
  394. * The Null WILL be copied (unless the Dest overflows)                       *
  395. * d7.w returns (#-1) if the destination is filled. If it is not filled,     *
  396. * d7.w returns the remaining length of the buffer. ***d7 RETURNS IN A WORD***
  397. *****************************************************************************
  398. CopyNTJ    Move.b    (a0)+,(a1)+        Copy the next char
  399.     DBeq    d7,CopyNTJ        Copy till end of dest or null reached
  400.     RTS
  401. CopyCNT    DBra    d7,CopyNTJ        Incase eq set before calling.
  402.     RTS
  403.     ENDC
  404.  
  405.     IFD    DATA_COPYCN2
  406. *= COPY CHARS NULL TERMINATED, DO NOT WRITE THE NULL =***********************
  407. * a0 - Null Terminated Source data.   * a1 - Destination Area               *
  408. * d7 = Max Length for Dest      (#-1) *                                     *
  409. *===========================================================================*
  410. * Branch to CopyCN2                                                         *
  411. *****************************************************************************
  412. CCN2_L    Tst.b    (a0)            End of String?
  413.     Beq.s    WrMNT2D            YES = Done.
  414.     Move.b    (a0)+,(a1)+        Write Memory...
  415. CopyCN2    DBra    d7,CCN2_L        Write more...
  416. WrMNT2D    RTS
  417.     ENDC
  418.  
  419.     IFD    DATA_COPYCN3
  420. *= COPY CHARS NULL TERMINATED, DO NOT WRITE THE NULL, NO LENGTH CHECK =******
  421. * a0 - Null Terminated Source data.   * a1 - Destination Area               *
  422. *****************************************************************************
  423. CopyCN3    Tst.b    (a0)            End of String?
  424.     Beq.s    CpyCN3D            YES = Done.
  425.     Move.b    (a0)+,(a1)+        Write Memory...
  426.     Bra.s    CopyCN3            Write more...
  427. CpyCN3D    RTS
  428.     ENDC
  429.  
  430. *= >>MACRO<< = Copy x bytes =************************************************
  431. ;CopyEm    MACRO
  432. ;    Bra.s    COPE2\@
  433. ;COPEM\@    Move.b    (a0)+,(a1)+
  434. ;COPE2\@    DBra    d7,COPEM\@
  435. ;    ENDC
  436.  
  437. *= >>MACRO<< = Copy NULL Term INCLUDING NULL, NO LENGTH CHECK =**************
  438. ;CopyCN4    MACRO            MOVED TO EQUATES
  439. ;CCN4\@    Move.b    (a0)+,(a1)+
  440. ;    Bne.s    CCN4\@
  441. ;    ENDM
  442.  
  443.     IFD    DATA_CPYDUAL
  444. *= COPY DUAL BYTE TERMINATOR =***********************************************
  445. * a0 = Start (End) Source String     * a1 = Start (End) Destin String       *
  446. * d0 - Chr to End Copy on (not copy) * d1 - Chr to Enb Copy on (not copied) *
  447. *===========================================================================*
  448. * After BSRing this routine: BEQ to routine for if the First (d0) is Found  *
  449. * -------------------------- BNE to routine for if the Secnd (d1) is Found  *
  450. *****************************************************************************
  451. CpyDual    Cmp.b    (a0),d0            End Char?
  452.     Beq.s    CopyDo0            Yes=Copy Done
  453.     Cmp.b    (a0),d1            End Char?
  454.     Beq.s    CopyDo1            Yes=Copy Done
  455.     Move.b    (a0)+,(a1)+        Else, Copy until end of destin.
  456.     Bra.s    Copy_Dual
  457. CopyDo0    Move    #EqCCR,CCR        d0 Was found. (Set Z CCR "Equal")
  458.     RTS
  459. CopyDo1    Move    #NeCCR,CCR        d1 Was found. (Clear Z CCR "NotEq")
  460.     RTS
  461.     ENDC
  462.  
  463.     IFND    DATA_SPAOVER
  464.     IFD    DATA_WRCHARS
  465. *= WRITE x CHARS =***********************************************************
  466. * d0 = Char to Write                  * a1 = Start (end+1) Destination Area *
  467. *                                     * d1 = Length of above          (#-1) *
  468. *****************************************************************************
  469. SO_L2    Move.b    d0,(a1)+        Write Fill-Pad Char
  470. OC_XXCh    DBra    d1,SO_L2        Do till Dest Full
  471.     RTS
  472.     ENDC
  473.     ENDC
  474.  
  475.     IFD    DATA_SPAOVER
  476. *= OVERLAY OUTPUT, AUTO SPACE PAD =******************************************
  477. * a1 = Start (end+1) Destination      * a0 = Start (end+1) Source String    *
  478. * d1 = Length of Above                * d3 - Length of above                *
  479. * d0 = Char to Fill remainder of dest *                                     *
  480. *===========================================================================*
  481. * SpaOver puts a space into d0                                              *
  482. *****************************************************************************
  483. SpaOver    Move.b    #" ",d0            Space Pad
  484. XXXOver    Cmp.l    d3,d1            -.  If string is longer than the
  485.     Bge.s    SO_J2             |- overlay, only do length(overlay)
  486.     Move.l    d1,d3            -'  chars. Else do length(string)
  487. SO_J2    Sub.l    d3,d1            Difference length(overlay|string)
  488.     Bra.s    SO_J3
  489. SO_L1    Move.b    (a0)+,(a1)+        Copy this byte...
  490. SO_J3    DBra    d3,SO_L1        Do till all chars written
  491.     Bra.s    SO_J1            Pad any chars remaining.
  492. SO_L2    Move.b    d0,(a1)+        Write Fill-Pad Char
  493. OC_XXCh
  494. SO_J1    DBra    d1,SO_L2        Do till Dest Full
  495.     RTS
  496.     ENDC
  497.  
  498.     IFD    DATA_N2AAuto
  499. *= NUMBER » ASCII, AUTOMATIC ROUTINE JUMPER TYPE THING =*********************
  500. * Regs = {As for NUMBER » ASCII}      *                                     *
  501. *****************************************************************************
  502. N2AAuto    Cmpi.l    #9,d1            -._ Branch if
  503.     Ble    N2A1Dig            -'  one digit
  504.     Cmpi.l    #99,d1            -._ Branch if
  505.     Ble    N2A2Dig            -'  two digits
  506.     Cmpi.l    #999,d1            -._ Branch if
  507.     Ble.s    N2A3Dig            -'  three digits
  508.     Cmpi.l    #9999,d1        -._ Branch if
  509.     Ble.s    N2A4Dig            -'  four digits
  510.     Cmpi.l    #99999,d1        -._ Branch if
  511.     Ble.s    N2A5Dig            -'  five digits
  512.     Cmpi.l    #999999,d1        -._ Branch if
  513.     Ble.s    N2A6Dig            -'  six digits
  514.     Cmpi.l    #9999999,d1
  515.     Ble.s    N2A7Dig
  516.     Move.b    #"[",(a1)+
  517.     Move.b    #"B",(a1)+
  518.     Move.b    #"I",(a1)+
  519.     Move.b    #"G",(a1)+
  520.     Move.b    #"]",(a1)+
  521.     RTS
  522.     ENDC
  523.  
  524.     IFD    DATA_NUM2ASC
  525. *= NUMBER » ASCII =**********************************************************
  526. * d1 = Input NUMBER (#0)              * d2 = [Div6+ Only] <Temp>            *
  527. * a1 = Start of ASCII output (end+1)  *                                     *
  528. *===========================================================================*
  529. * Call the routine depending on how many Digits the number has              *
  530. *****************************************************************************
  531. N2A7Dig    Moveq    #-1,d2            Clear D2 for # of 1000 thous.
  532. N2A7Loo    Addq.b    #1,d2            Add 1 to # of 1000 thous.
  533.     Sub.l    #1000000,d1        Take 1000thou from the number
  534.     Bpl.s    N2A7Loo            Branch if number is still +ve
  535. N2A7End    Add.l    #1000000,d1        Make it +ve again.
  536.     Add.b    #$30,d2            Make number in d2 Ascii
  537.     Move.b    d2,(a1)+        Write it!
  538.  
  539. N2A6Dig    Moveq    #-1,d2            Clear D2 for # of 100 thous.
  540. N2A6Loo    Addq.b    #1,d2            Add 1 to # of 100 thous.
  541.     Sub.l    #100000,d1        Take 100 from the number
  542.     Bpl.s    N2A6Loo            Branch if number is still +ve
  543. N2A6End    Add.l    #100000,d1        Make it +ve again.
  544.     Add.b    #$30,d2            Make number in d2 Ascii
  545.     Move.b    d2,(a1)+        Write it!
  546.  
  547. N2A5Dig    Divu.w    #10000,d1
  548.     Bsr.s    N2A1Dig
  549. N2A4Dig    Divu.w    #1000,d1        How many thousands?
  550.     Bsr.s    N2A1Dig            Turn into ascii
  551. N2A3Dig    Divu.w    #100,d1            How many hundreds?
  552.     Bsr.s    N2A1Dig            Turn into ascii
  553. N2A2Dig    Divu.w    #10,d1            How many tens?
  554.     Opt    O-            -.
  555.     Bsr    N2A1Dig             |- Do NOT convert to short branch!!
  556.     Opt    O+            -'
  557. N2A1Dig    Add.b    #$30,d1            Convert
  558.     Move.b    d1,(a1)+        Move byte into string
  559.     Swap    d1            Swap for remainder
  560.     And.l    #$FFFF,d1        Clear High Word
  561.     RTS
  562.     ENDC
  563.  
  564.  
  565.     IFD    DATA_N2ASCFT
  566. *= NUMBER » ASCII for Format-Text, JUMPER for below routine =****************
  567. * As for the below routine, but sets up D4 and fixes output of "0".         *
  568. * The desired routine should be LEA'd into A2                               *
  569. *===========================================================================*
  570. * e.g.    Move.l    #1234567,d2        Nº to convert.                      *
  571. *    Lea    NAB7Dig(pc),a2        7 Digit Number.                     *
  572. *    Bsr    NABJump            Convert it.                         *
  573. *****************************************************************************
  574. NABJump    Moveq    #0,d4            Clear d4 for Pad-Zero routine.
  575.     Jsr    (a2)            Jump to the wanted subroutine.
  576.     Cmpi.b    #" ",-1(a1)        Was the last digit a space?
  577.     Bne.s    NABJJmp            NOPE = All'swell just return.
  578.     Move.b    #"0",-1(a1)        Else Nº was zero, correct it.
  579. NABJJmp    RTS
  580.  
  581. *= NUMBER » ASCII for Format-Text, with auto Pad-Zero =**********************
  582. * d4 = MUST BE CLEARED BEFORE CALLING *  d0 - Nº Chars written.             *
  583. * d2 = Input NUMBER (#0)              * (a1) = Current possition in block.  *
  584. * d3 = [Div6+ Only] <Temp>            * (d6) - End of output-block.         *
  585. *===========================================================================*
  586. * Normally this routine should be called by the above Jumper routine.       *
  587. * Call the routine depending on how many Digits the number has.             *
  588. * Remember to clear d4 before calling. Unless Pad-Zero is not wanted, in    *
  589. *  which case bit 0 should be set before calling.                           *
  590. *****************************************************************************
  591. NAB7Dig    Moveq    #-1,d3            Clear d2 for Nº 1000 thousands.
  592. NAB7Loo    Addq.b    #1,d3            Increment Nº of 1000 thousands found.
  593.     Sub.l    #1000000,d2        Take 1000 thousand from the number,
  594.     Bpl.s    NAB7Loo            Do again if number is still +ve.
  595.     Add.l    #1000000,d2        Get the correct remainder.
  596.     Exg.l    d2,d3            Give the output subroutine the digit.
  597.     Bsr.s    NAB1Dig            Output the digit.
  598.     Move.l    d3,d2            Move number to be used over digit.
  599. NAB6Dig    Moveq    #-1,d3            Clear d2 for Nº 100 thousands.
  600. NAB6Loo    Addq.b    #1,d3            Increment Nº of 100 thousands found.
  601.     Sub.l    #100000,d2        Take 100 thousand from the number,
  602.     Bpl.s    NAB6Loo            Do again if number is still +ve.
  603.     Add.l    #100000,d2        Get the correct remainder.
  604.     Exg.l    d2,d3            Give the output subroutine the digit.
  605.     Bsr.s    NAB1Dig            Output the digit.
  606.     Move.l    d3,d2            Move number to be used over digit.
  607. NAB5Dig    Divu    #10000,d2        How many 10 thousands?
  608.     Bsr.s    NAB1Dig
  609. NAB4Dig    Divu    #1000,d2        How many thousands?
  610.     Bsr.s    NAB1Dig
  611. NAB3Dig    Divu    #100,d2            How many 100s?
  612.     Bsr.s    NAB1Dig
  613. NAB2Dig    Divu    #10,d2            How many 10s?
  614.     OPT    O-
  615.     Bsr    NAB1Dig
  616.     OPT    O+
  617. NAB1Dig    BTst    #0,d4            Has the 1st real digit been written?
  618.     Bne.s    NABRDig            YES = Don't check this for #0 then.
  619.     Tst.b    d2            Is this digit zero?
  620.     Beq.s    NABZero            YES = Pad it with a space.
  621.     BSet    #0,d4            Set bit as 1st real digit written.
  622. NABRDig    Add.b    #$30,d2            ELSE... Convert number to ASCII digit
  623.     Cmp.l    d6,a1            -.
  624.     Blt.s    NABNor1             |- End of block = Allocate another
  625.     Bsr    AlocOutBlock        -'
  626. NABNor1    Move.b    d2,(a1)+        Write the digit.
  627.     Addq.l    #1,d0            Increment Nº output chars.
  628.     Swap    d2            Swap for remainder,
  629.     And.l    #$FFFF,d2        and clear unwanted high word.
  630.     RTS
  631.  
  632. NABZero    Cmp.l    d6,a1            -.
  633.     Blt.s    NABNorZ             |- End of block = Allocate another
  634.     Bsr    AlocOutBlock        -'
  635. NABNorZ    Move.b    #" ",(a1)+        Write the space.
  636.     Addq.l    #1,d0            Increment Nº chars written.
  637.     Swap    d2            Swap for remainder,
  638.     And.l    #$FFFF,d2        and clear unwanted high word.
  639.     RTS
  640.     ENDC
  641.  
  642.  
  643.     IFD    DATA_ASC2NUM
  644.     IFD    DATA_AS2NUNT
  645. *= ASCII » NUMBER, NULL TERM =***********************************************
  646. * a0 = Start (End+1) of ASCII number  * d0 = <Temp> (Return Number)         *
  647. * Regs = {And those of Asc2Num below} *                                     *
  648. *****************************************************************************
  649. As2NuNT    Move.l    a0,a1            Preserve point to ASCII number.
  650.     Moveq    #-1,d2            -.
  651. CountDL    Addq.l    #1,d2             |_ Count the number
  652.     Tst.b    (a1)+             |  of digits.
  653.     Bne.s    CountDL            -'
  654. ;;;;;;;    Bra    Asc2Num            Raw Number -> d0
  655.     ENDC
  656.  
  657. ; [This space is part of the ASCII » NUMBER include!]
  658. ;;;;;;;    If a routine must be added here, remember to remove the ;'s before the
  659. ;;;;;;;    above "Bra    Asc2Num" !!!
  660.  
  661. *= ASCII » NUMBER =**********************************************************
  662. * a0 = Start (End+1) of ASCII number  * d0 = <Temp> (Return Number)         *
  663. * d1 = <Temp> (#0)                    * d2 = No. digits (#-1)               *
  664. *                                     * d7 = <Temp>                         *
  665. * {When changing this routine, keep in mind the Hrs2Min routine below}      *
  666. *****************************************************************************
  667. Asc2Num    Moveq    #0,d0            -._ ready for conversion
  668.     Moveq    #0,d1            -'  (Clear for .b moves)
  669.     Bra.s    A2NJmp1            Do x number of digits.
  670. A2NMain    Move.b    (a0)+,d1        Get the next digit
  671.     Sub.b    #$30,d1            Ascii » Number
  672.     Asl.l    #1,D0            -.
  673.     Move.l    D0,D7             |_ Long-Word Multiply
  674.     Asl.l    #2,D0             |  Old Number by 10.
  675.     Add.l    D7,D0            -'
  676.     Add.l    d1,d0            Add the new number
  677. A2NJmp1    DBra    d2,A2NMain        Do till all digits done.
  678.     RTS
  679.  
  680. ; [This space is part of the ASCII » NUMBER include!]
  681.  
  682.     IFD    DATA_TIMECON
  683. *= TIME CONVERTER =************************************************************
  684. * a0 = Start (end) of HH:MM (ASCII)    * d0 = (Number of mins)                *
  685. * AND {those used in Asc2Num routine}  *                                      *
  686. *******************************************************************************
  687. Hrs2Min    Moveq    #2,d2            2 Digits to convert
  688.     Bsr.s    Asc2Num            Convert HH(ASCII) to a Raw Number
  689.     Mulu.w    #60,d0            Convert Hours to Minutes
  690.     Move.l    d0,-(SP)        Preserve d0
  691.  
  692.     Addq.l    #1,a0            Point to MM (Skip the ":")
  693.     Moveq    #2,d2            2 Digits to convert
  694.     Bsr.s    Asc2Num            Convert MM(ASCII) to a Raw Number
  695.     Add.l    (SP)+,d0        Add the hours and mins together
  696.     RTS
  697.     ENDC
  698.     ENDC
  699.  
  700.  
  701.     IFD    DATA_PADZERO
  702. *= PAD ZEROS =***************************************************************
  703. * a1 = Start (End+1) of ASCII number   * d1 = No. Digits to do. (#-1)       *
  704. *                                      *      Usually #Digits-1, so that if *
  705. *                                      *      the #=0 it's not cleared.     *
  706. *===========================================================================*
  707. * BSR to NoZero                                                             *
  708. *****************************************************************************
  709. NoZeroL    Cmpi.b    #"0",(a1)        Is this a 0?
  710.     Bne.s    Zerod            No! End routine.
  711.     Move.b    #" ",(a1)+        Space the 0
  712. NoZero    DBra    d1,NoZeroL        Do x Digits.
  713. Zerod    RTS
  714.     ENDC
  715.  
  716.     IFD    DATA_DQUOTER
  717. *= FILE NAME DEQUOTER =******************************************************
  718. * a0 = Start (End+1) of Filename      *                                     *
  719. *===========================================================================*
  720. * Nulls the 1st Quote (") it finds. For CommandLine Use                     *
  721. *****************************************************************************
  722. ** Should use registers instead of immediate data... Find out what regs are
  723. ** free by whatever programs use this routine and use them.
  724. ****
  725. DQuoter    Cmpi.b    #$22,(a0)        Is this the Quote?
  726.     Beq.s    GotQuot            Yes=Null it and return
  727.     Cmpi.b    #10,(a0)+        Is this the end of the command line?
  728.     Beq    InvaTex            Yes=Invalid Commandline
  729.     Bra.s    DQuoter            Noo=Check Next letter
  730. GotQuot    Move.b    #0,(a0)+        Null the Quote & Point past it
  731.     RTS
  732.     ENDC
  733.  
  734.     IFD    DATA_EXPLODE
  735. *= EXPLODE IMPLODER-CRUNCHED DATA =*******= Written by Albert J. Brouwer =**
  736. * a0 = Start of Crunched data file AND memory to Explode into!             *
  737. * The memory must be the size of the UNCRUNCHED data, and on an even adr!  *
  738. ****************************************************************************
  739. ExplodeData    movem.l    d2-d5/a2-a4,-(sp)
  740.         move.l    a0,a3
  741.         move.l    a0,a4
  742.         cmp.l    #'IMP!',(a0)+
  743.         bne.s    Explode012
  744.         add.l    (a0)+,a4
  745.         add.l    (a0)+,a3
  746.         move.l    a3,a2
  747.         move.l    (a2)+,-(a0)
  748.         move.l    (a2)+,-(a0)
  749.         move.l    (a2)+,-(a0)
  750.         move.l    (a2)+,d2
  751.         move.w    (a2)+,d3
  752.         bmi.s    Explode00D
  753.         subq.l    #1,a3
  754. Explode00D    lea    -28(sp),sp
  755.         move.l    a7,a1
  756.         moveq    #6,d0
  757. Explode00E    move.l    (a2)+,(a1)+
  758.         dbra    d0,Explode00E
  759.         move.l    a7,a1
  760.         moveq    #0,d4
  761. Explode00F    tst.l    d2
  762.         beq.s    Explode011
  763. Explode010    move.b    -(a3),-(a4)
  764.         subq.l    #1,d2
  765.         bne.s    Explode010
  766. Explode011    cmp.l    a4,a0
  767.         bcs.s    Explode014
  768.         lea    28(sp),sp
  769.         moveq    #-1,d0
  770.         cmp.l    a3,a0
  771.         beq.s    Explode013
  772. Explode012    moveq    #0,d0
  773. Explode013    movem.l    (sp)+,d2-d5/a2-a4
  774.         move.l    d0,d0
  775.         rts
  776. Explode014    add.b    d3,d3
  777.         bne.s    Explode015
  778.         move.b    -(a3),d3
  779.         addx.b    d3,d3
  780. Explode015    bcc.s    Explode021
  781.         add.b    d3,d3
  782.         bne.s    Explode016
  783.         move.b    -(a3),d3
  784.         addx.b    d3,d3
  785. Explode016    bcc.s    Explode020
  786.         add.b    d3,d3
  787.         bne.s    Explode017
  788.         move.b    -(a3),d3
  789.         addx.b    d3,d3
  790. Explode017    bcc.s    Explode01F
  791.         add.b    d3,d3
  792.         bne.s    Explode018
  793.         move.b    -(a3),d3
  794.         addx.b    d3,d3
  795. Explode018    bcc.s    Explode01E
  796.         add.b    d3,d3
  797.         bne.s    Explode019
  798.         move.b    -(a3),d3
  799.         addx.b    d3,d3
  800. Explode019    bcc.s    Explode01a
  801.         move.b    -(a3),d4
  802.         moveq    #3,d0
  803.         bra.s    Explode022
  804. Explode01a    add.b    d3,d3
  805.         bne.s    Explode01B
  806.         move.b    -(a3),d3
  807.         addx.b    d3,d3
  808. Explode01B    addx.b    d4,d4
  809.         add.b    d3,d3
  810.         bne.s    Explode01C
  811.         move.b    -(a3),d3
  812.         addx.b    d3,d3
  813. Explode01C    addx.b    d4,d4
  814.         add.b    d3,d3
  815.         bne.s    Explode01D
  816.         move.b    -(a3),d3
  817.         addx.b    d3,d3
  818. Explode01D    addx.b    d4,d4
  819.         addq.b    #6,d4
  820.         moveq    #3,d0
  821.         bra.s    Explode022
  822. Explode01E    moveq    #5,d4
  823.         moveq    #3,d0
  824.         bra.s    Explode022
  825. Explode01F    moveq    #4,d4
  826.         moveq    #2,d0
  827.         bra.s    Explode022
  828. Explode020    moveq    #3,d4
  829.         moveq    #1,d0
  830.         bra.s    Explode022
  831. Explode021    moveq    #2,d4
  832.         moveq    #0,d0
  833. Explode022    moveq    #0,d5
  834.         move.w    d0,d1
  835.         add.b    d3,d3
  836.         bne.s    Explode023
  837.         move.b    -(a3),d3
  838.         addx.b    d3,d3
  839. Explode023    bcc.s    Explode026
  840.         add.b    d3,d3
  841.         bne.s    Explode024
  842.         move.b    -(a3),d3
  843.         addx.b    d3,d3
  844. Explode024    bcc.s    Explode025
  845.         move.b    Explode030(pc,d0.w),d5
  846.         addq.b    #8,d0
  847.         bra.s    Explode026
  848. Explode025    moveq    #2,d5
  849.         addq.b    #4,d0
  850. Explode026    move.b    Explode031(pc,d0.w),d0
  851. Explode027    add.b    d3,d3
  852.         bne.s    Explode028
  853.         move.b    -(a3),d3
  854.         addx.b    d3,d3
  855. Explode028    addx.w    d2,d2
  856.         subq.b    #1,d0
  857.         bne.s    Explode027
  858.         add.w    d5,d2
  859.         moveq    #0,d5
  860.         move.l    d5,a2
  861.         move.w    d1,d0
  862.         add.b    d3,d3
  863.         bne.s    Explode029
  864.         move.b    -(a3),d3
  865.         addx.b    d3,d3
  866. Explode029    bcc.s    Explode02C
  867.         add.w    d1,d1
  868.         add.b    d3,d3
  869.         bne.s    Explode02a
  870.         move.b    -(a3),d3
  871.         addx.b    d3,d3
  872. Explode02a    bcc.s    Explode02B
  873.         move.w    8(a1,d1.w),a2
  874.         addq.b    #8,d0
  875.         bra.s    Explode02C
  876. Explode02B    move.w    (a1,d1.w),a2
  877.         addq.b    #4,d0
  878. Explode02C    move.b    16(a1,d0.w),d0
  879. Explode02D    add.b    d3,d3
  880.         bne.s    Explode02E
  881.         move.b    -(a3),d3
  882.         addx.b    d3,d3
  883. Explode02E    addx.l    d5,d5
  884.         subq.b    #1,d0
  885.         bne.s    Explode02D
  886.         addq.l    #1,a2
  887.         add.l    d5,a2
  888.         add.l    a4,a2
  889. Explode02F    move.b    -(a2),-(a4)
  890.         subq.b    #1,d4
  891.         bne.s    Explode02F
  892.         bra    Explode00F
  893. Explode030    dc.w    $060a,$0a12
  894. Explode031    dc.b    1,1,1,1,2,3,3,4,4,5,7,14
  895.     ENDC
  896.  
  897.     IFD    DATA_NULLLEN
  898. *= NULL-TERMATED LENGTH CALCULATOR =***********************************= 18-Aug-1995 =*
  899. *  Inputs: (a0) - Start of null-terminated string to count.                  *
  900. * Outputs: (a0) - The null-terminator of the counted string.                  *
  901. *           d0  - Length of the string, excluding the null.                  *
  902. *   Notes: Guaranteed not to alter any registers apart from a0/d0 in the future.      *
  903. ***************************************************************************************
  904. NullLen    Moveq    #-1,d0            Reset Length to ZERO, -1
  905. NullLeL    Addq.l    #1,d0            Add 1 to number of chars...
  906.     Tst.b    (a0)+            Is this a Null?
  907.     Bne.s    NullLeL            Nope, Keep counting...
  908.     Subq.l    #1,a0            Point back to the null.
  909.     RTS
  910.     ENDC
  911.  
  912.     IFD    DATA_RNDBYTE
  913.     IFD    DATA_RNDWORD
  914. *= RANDOM (WORD-SIZE) =******************************************************
  915. * d5 - Maximum+1 [From 0 -> 65536]    * d3 = ("Rnd"# [From 0 -> Maximum])   *
  916. * {And as for RndByte Routine Below}  *                                     *
  917. *****************************************************************************
  918. RndWord    Move.l    #256,d0
  919.     Bsr.s    RndByte            Get a # from $00-$FF
  920.     Move.l    d1,d3
  921.     Asl.l    #8,d3            Shift into upper word.
  922.     Bsr.s    RndByte            Another from $00-$FF
  923.     Add.l    d1,d3            Move into lower word.
  924.     
  925.     Mulu.w    d5,d3            Out of <d5>...
  926.     Lsr.l    #8,d3            ...not $FFFF
  927.     Lsr.l    #8,d3
  928.     RTS
  929.     ENDC
  930. ;
  931. ;    THIS SPACE IS PART OF THE RNDBYTE INCLUDE
  932. ;
  933. *= RANDOM (BYTE-SIZE) =******************************************************
  934. * d0 - Maximum+1 [From 0 -> 256]      * d1 = ("Rnd"# [From 0 -> Maximum])   *
  935. * d2 = <Temp>                         *                                     *
  936. *****************************************************************************
  937. RndByte    Movem.l    d0/d3-d7/a0-a4/a6,-(SP)    -.
  938. ;;;;;;;    Move.l    DosBase(a5),a6         |
  939.     Lea    DTStruc(a5),a0         |_ Put DateStamp into  
  940.     Move.l    a0,d1             |  the DateTime Structure.
  941.     CALLDOS    DateStamp         |
  942.     Movem.l    (SP)+,d0/d3-d7/a0-a4/a6    -'
  943.     Move.b    DT_Days+3(a5),d2
  944.     Add.b    d2,d2
  945.     Eor.b    #$A1,d2
  946.     Move.b    DT_Mins+3(a5),d1
  947.     Eor.b    #$F9,d1
  948.     Add.b    d2,d1
  949.     Dc.b    $D2,$39,$00,$DF,$F0,$07    (Add.b    $dff007,d1)
  950.     Move.b    DT_Tiks+3(a5),d2
  951.     Add.b    d2,d2
  952.     Eor.b    d2,d1
  953.     Dc.b    $D2,$39,$00,$DF,$F0,$07    (Add.b    $dff007,d1)
  954.     Dc.b    $D2,$39,$00,$DF,$F0,$06    (Add.b    $dff006,d1)
  955.     And.l    #$FF,d1            Clear any junk from previous uses.
  956.     Mulu.w    d0,d1            Out of <d0>...
  957.     Lsr.w    #8,d1            ...not 256
  958.     RTS
  959.     ENDC
  960.  
  961.     IFD    DATA_RNDLEPP
  962. *= RANDOM (WORD-SIZE) =*****************************=- by Andrew Leppard -=**
  963. * d5 - Maximum+1 [From 1 -> 65536]    * d3 = ("Rnd"# [From 0 -> Maximum])   *
  964. * d2 = <TEMP>                         *                                     *
  965. *****************************************************************************
  966. * I found and modified this source hoping for a better random-number        *
  967. * routine than my own, however, it appears that MY RNDWORD is more random   *
  968. * than this one (actually, I think mine is not as crap as I thought!)...    *
  969. * Based on 10000 repeated calls to each routine for 0-20, this one seems to *
  970. * consistantly return twice as much of certain numbers than others, while   *
  971. * mine is more or less evenly distributed, without a greatly noticable bias *
  972. * towards any number. However, I don't know if it's a fair test, perhaps    *
  973. * when the time between each execution of the routine is so similar it      *
  974. * becomes less random... His certainly uses more seeds than mine...         *
  975. *****************************************************************************
  976. RndLepp    Movem.l    d0-1/d4/d6-d7/a0-a6,-(SP)    -.
  977.     Lea    DTStruc(a5),a0             |  Put DateStamp into  
  978.     Move.l    a0,d1                 |- the DateTime Structure.
  979.     CALLDOS    DateStamp             |
  980.     Movem.l    (SP)+,d0-1/d4/d6-d7/a0-a6    -'
  981.  
  982.     Clr.l    d3
  983.     Clr.l    d2
  984.  
  985.     Move.b    $bfe400,d3        ;CIA-A Timer A: Lo
  986.     Move.b    $bfd600,d2        ;CIA-B Timer B: Lo
  987.     Eor.l    d2,d3
  988.     Move.b    $bfd400,d2        ;CIA-B Timer A: Lo
  989.     And.l    #%11111,d2
  990.     Rol.l    d2,d3
  991.     Move.b    $bfe7000,d2        ;CIA-A Timer B: Lo
  992.     Ror.l    d2,d3
  993.  
  994.     Move.w    $dff004,d2        ;Raster screen pos
  995.     Eor.w    d2,d3
  996.     Move.w    $dff006,d2        ;Raster screen pos
  997.     Eor.w    d2,d3
  998.     Move.l    DT_Tiks(a5),d2        ;AmigaDATE!
  999.     Eor.l    d2,d3
  1000.     Move.l    DT_Mins(a5),d2
  1001.     Eor.l    d2,d3
  1002.     Move.l    DT_Days(a5),d2
  1003.     Eor.l    d2,d3
  1004.     Move.l    d3,d2
  1005.     Swap    d2            ;use 2nd word as another rnd source
  1006.     Eor.w    d2,d3
  1007.  
  1008. ;;;;;;;    Addq.l    #1,d5            P0T: Now expects Max+1, not Max
  1009.     Mulu.w    d5,d3            -.               (Max+1)
  1010.     Divu.w    #65535,d3         |- Multiply by  -------
  1011.     And.l    #$0000FFFF,d3        -'                65535
  1012.  
  1013.     Cmp.l    d3,d5            -.
  1014.     Bne.s    RNDLEPJ             |- If = Max+1, Set to Max
  1015.     Subq.l    #1,d3            -'
  1016. RNDLEPJ    RTS
  1017.     ENDC
  1018.  
  1019.  
  1020.     IFD    DATA_NUWRAND
  1021. *****************************************************************************
  1022. * Generate a "random" seed-word for the Random Number routine.            *
  1023. *===========================================================================*
  1024. * Note: This routine uses the system time and thus will not work very well  *
  1025. * ----- for people who don't have a set clock.                    *
  1026. *===========================================================================*
  1027. * Consider all registers destroyed.                        *
  1028. *****************************************************************************
  1029. RndSeed
  1030.     Lea    DTStruc(a5),a0        -.
  1031.     Move.l    a0,d1             |- Set DateTime Structure.
  1032.     CALLDOS    DateStamp        -'
  1033.  
  1034.     Move.w    DT_Days+2(a5),d0
  1035.     Mulu.w    #24*60,d0        Days -> Minutes.
  1036.     Add.w    DT_Mins+2(a5),d0
  1037.     Mulu.w    #60,d0            Minutes -> Seconds.
  1038.  
  1039.     Add.w    DT_Tiks+2(a5),d0
  1040.  
  1041. ;    Move.w    DT_Tiks+2(a5),d1
  1042. ;    Divu.w    #50,d1            Ticks -> Seconds.
  1043. ;    Add.w    d1,d0            Total seconds since 1978.
  1044.  
  1045.     Move.w    d0,-(SP)        -.
  1046.     CALLGFX    VBeamPos         |- Add Vertical Beam
  1047.     Mulu.w    #64,d0             |
  1048.     Add.w    (SP)+,d0        -'
  1049.  
  1050.     And.l    #$FFFF,d0        Clear upper word.
  1051.     Cmpi.l    #32768,d0        -.
  1052.     Ble.s    RndSeed_Skp1         |- If over 32768, half.
  1053.     Lsr.l    #1,d0            -'
  1054. RndSeed_Skp1
  1055.     Move.w    d0,WordSeed(a5)        Store seed for later.
  1056.     RTS
  1057. *****************************************************************************
  1058. * Get next "random" number in sequence generated by the seed value.        *
  1059. *****************************************************************************
  1060. * d7.w = (NewSeed)              *    WordSeed.w = Seed, (NewSeed)     *
  1061. *===========================================================================*
  1062. * With thanks to Christopher Jennings, u9303286@muss.cis.mcmaster.ca        *
  1063. *****************************************************************************
  1064. NextSeed
  1065.     Move.w    WordSeed(a5),d7
  1066.     Mulu.w    #5,d7
  1067.     Add.l    #12479,d7    Any odd number here will generate a diff. sequence
  1068.     Divu.w    #32768,d7
  1069.     Clr    d7
  1070.     Swap    d7
  1071.     Move.w    d7,WordSeed(a5)
  1072.     RTS
  1073. *****************************************************************************
  1074. * Call NextSeed, and then return a result within a given range.            *
  1075. *****************************************************************************
  1076. * d0.w = Maximum number               * WordSeed.w = Seed, (NewSeed)        *
  1077. * d7.w = Number (#0 to d0.w-1)        *                                     *
  1078. *****************************************************************************
  1079. RangeSeed
  1080.     Bsr.s    NextSeed
  1081.     Mulu.w    d0,d7            -._ Out of do,
  1082.     Divu.w    #32768,d7        -'  not 32768 (= 2^15).
  1083.     And.l    #$FFFF,d7
  1084.     RTS
  1085.  
  1086.     ENDC
  1087.  
  1088.  
  1089.     IFD    DATA_RAWDOFMT
  1090. *= NudelRawDoFmt =*****************************************************= 11-Aug-1995 =*
  1091. *  Inputs: a0 - Null-term Input string containing % commands etc.              *
  1092. *       a1 - Datastream.                                  *
  1093. *       RDF_Adrs(a5) - Address of Output-buffer.                      *
  1094. *       RDF_Size(a5) - Size of Output-buffer.                      *
  1095. * Outputs: Formatted null-term string at where a3 used to point.              *
  1096. ***************************************************************************************
  1097. NudelRawDoFmt
  1098.     Lea    NudelRawDoFmt_Proc(pc),a2    Procedure to call for each char.
  1099.     Move.l    a5,a3                Preserve a3 (not touched by RawDoFmt()
  1100.     N_CallExec    RawDoFmt
  1101.     Tst.l    RDF_Size(a5)            -._ If the buffer overflowed,
  1102.     Ble    Buffer_Overflow            -'  print fatal error message.
  1103.     RTS
  1104.  
  1105. NudelRawDoFmt_Proc
  1106.     Tst.l    RDF_Size(a3)            -._ If the buffer if full, do
  1107.     Ble.s    NudelRawDoFmt_Skip        -'  not write any more into it.
  1108.     Move.l    a3,-(SP)            Preserve a3
  1109.     Move.l    RDF_Adrs(a3),a3            Get adrs to write out to.
  1110.     Move.b    d0,(a3)                Output the next character.
  1111.     Move.l    (SP)+,a3            Preserve a3
  1112.     Addq.l    #1,RDF_Adrs(a3)            Update adrs to write to.
  1113.     Subq.l    #1,RDF_Size(a3)            Update the remaining length.
  1114. NudelRawDoFmt_Skip
  1115.     RTS
  1116.     ENDC
  1117.